package com.jokerku.mini.schedule.config;

import com.jokerku.mini.schedule.common.Constants;
import com.jokerku.mini.schedule.domain.ZkPath;
import com.jokerku.mini.schedule.service.ZkCuratorServer;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @Author: guzq
 * @CreateTime: 2023/06/07 11:11
 * @Description: 分布式锁控制
 * @Version: 1.0
 */
//@Aspect
//@Component("mini-schedule-lock")
public class MiniScheduleLock {

    private static final Logger logger = LoggerFactory.getLogger(MiniScheduleLock.class);

    @Pointcut("@annotation(com.jokerku.mini.schedule.annotation.MiniScheduled)")
    public void point() {

    }

    @Around("point()")
    public Object doAround(ProceedingJoinPoint pj) throws Exception {
        // beanName_methodName
        InterProcessMutex lock = null;
        try {
            String taskId = getTaskId(pj);
            String path = ZkPath.getLockPath() + Constants.Global.HORIZONTAL_LINE + taskId;
            lock = ZkCuratorServer.getLock(Constants.Global.client, path);
            boolean acquire = lock.acquire(1, TimeUnit.SECONDS);
            return pj.proceed();
        } catch (Throwable e) {
            logger.error("get mini schedule lock error", e);
            throw new RuntimeException(e);
        } finally {
            if (lock != null) {
                lock.release();
            }
        }

    }

    private String getTaskId(ProceedingJoinPoint pj) throws NoSuchMethodException {
        MethodSignature signature = (MethodSignature) pj.getSignature();
        Class<?> clazz = pj.getTarget().getClass();
        String className = clazz.getSimpleName();
        Method method = clazz.getMethod(signature.getName(), signature.getParameterTypes());
        String methodName = method.getName();

        String taskId = className + Constants.Global.HORIZONTAL_LINE + methodName;
        logger.info("获取 taskId :{}", taskId);

        return taskId;
    }


}
